package cn.yx.common.web.advice;

import cn.yx.common.core.enums.http.HttpHeaderCustomEnum;
import cn.yx.common.core.pojo.ResponseVo;
import cn.yx.common.i18n.service.I18nMessageService;
import cn.yx.sys.remote.dto.SysI18nMessageRemoteDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * <p>统一处理ResponseVo响应对象，如对message进行国际化处理</p>
 *
 * @author Wgsssmart
 */
@ControllerAdvice
@Slf4j
public class AppResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    private final I18nMessageService i18nMessageService;

    public AppResponseBodyAdvice(I18nMessageService i18nMessageService) {
        this.i18nMessageService = i18nMessageService;
    }

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return returnType.getParameterType() == ResponseVo.class;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof ResponseVo) {
            String transactionId = "";
            if (request instanceof ServletServerHttpRequest) {
                HttpServletRequest httpServletRequest = ((ServletServerHttpRequest) request).getServletRequest();
                transactionId = httpServletRequest.getAttribute(HttpHeaderCustomEnum.TRANSACTION_ID.getName()).toString();
            }
            return rewriteResponseVo(body, transactionId);
        }
        return body;
    }

    private ResponseVo<?> rewriteResponseVo(Object body, String transactionId) {
        log.info("rewrite response vo");
        ResponseVo<?> responseVo = (ResponseVo<?>) body;
        responseVo.setTransId(transactionId);
        SysI18nMessageRemoteDto sysI18nMessageRemoteDto = i18nMessageService.getSysI18nMessage(responseVo.getMessage(), responseVo.getMessageParams());
        responseVo.setMessage(sysI18nMessageRemoteDto.getMessage());
        return responseVo;
    }
}
